package ch6.pool.customer;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

/**
 * 类说明：自定义线程池实现
 */
public class MyThreadPool {

    /*缺省线程数据量*/
    private static int MAX_WORK_COUNT = 5;

    /*存放任务*/
    private final BlockingQueue<Runnable> taskQueue;
    /*工作线程*/
    private WorkThread[] workThreads;
    //工作线程数量
    private int WORK_COUNT;

    public MyThreadPool() {
        this(100, MAX_WORK_COUNT);
    }


    /**
     * 1.构造函数初始化线程池
     *
     * @param task_count  任务数
     * @param work_number 工作线程数
     */
    public MyThreadPool(int task_count, int work_number) {
        if (work_number <= 0) {
            work_number = MAX_WORK_COUNT;
        }
        if (task_count <= 0) {
            task_count = 100;
        }
        this.taskQueue = new ArrayBlockingQueue<>(task_count);
        this.WORK_COUNT = work_number;
        workThreads = new WorkThread[work_number];
        /*工作线程准备好了*/
        for (int i = 0; i < work_number; i++) {
            workThreads[i] = new WorkThread();
            workThreads[i].start();
        }
    }

    /**
     * 2.销毁线程池
     */
    public void destroy() {
        System.out.println("ready close pool....");
        int WORK_COUNT_SIGN = WORK_COUNT;
        for (int i = 0; i < WORK_COUNT_SIGN; i++) {
            workThreads[i].stopWorker();
            workThreads[i] = null;//help gc
            WORK_COUNT--;
        }
        taskQueue.clear();
    }


    /**
     * 3.放入任务，但是只是加入队列*
     *
     * @param task 任务
     */
    public void execute(Runnable task) {
        try {
            taskQueue.put(task);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    @Override
    public String toString() {
        return "工作线程数:" + WORK_COUNT + " 等待任务数:" + taskQueue.size();
    }


    /*内部类，工作线程的实现*/
    private class WorkThread extends Thread {
        @Override
        public void run() {
            Runnable r = null;
            try {
                while (!isInterrupted()) {
                    r = taskQueue.take();
                    System.out.println(getId() + " ready execute" + ((TestMyThreadPool.MyTask) r).getName());
                    r.run();
                    r = null;
                }
            } catch (InterruptedException e) {
                //e.printStackTrace();
            }

        }

        /*停止工作*/
        private void stopWorker() {
            interrupt();
        }
    }


}
